package org.example.controller;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import io.swagger.annotations.ApiOperation;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import net.sf.jsqlparser.expression.*;
import net.sf.jsqlparser.expression.operators.conditional.AndExpression;
import net.sf.jsqlparser.expression.operators.relational.EqualsTo;
import net.sf.jsqlparser.schema.Column;
import net.sf.jsqlparser.schema.Table;
import net.sf.jsqlparser.statement.select.*;
import net.sf.jsqlparser.util.SelectUtils;
import org.example.bean.req.DimensionQuery;
import org.example.bean.req.DrillReq;
import org.example.bean.req.HomePageDataReq;
import org.example.bean.res.HomePageDataRes;
import org.example.dao.entity.DynamicViewColumn;
import org.example.dao.entity.DynamicViewConfig;
import org.example.dao.entity.DynamicViewGroup;
import org.example.dao.mapper.DynamicViewColumnMapper;
import org.example.dao.mapper.DynamicViewConfigMapper;
import org.example.dao.mapper.DynamicViewGroupMapper;
import org.example.utils.JSqlParserUtil;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.*;

@Slf4j
@RestController
@AllArgsConstructor
@RequestMapping(value = "/drill")
public class DimensionDrillController {

    private final DynamicViewGroupMapper dynamicViewGroupMapper;
    private final DynamicViewConfigMapper dynamicViewConfigMapper;
    private final DynamicViewColumnMapper dynamicViewColumnMapper;

    /**
     * http://localhost:8081/drill?viewConfigId=1&sortField=productAmount&sortType=desc
     */
    @GetMapping("")
    @ApiOperation("获取下钻数据")
    public Object drill(DrillReq req) {
        DynamicViewConfig viewConfig = dynamicViewConfigMapper.selectById(req.getViewConfigId());
        DynamicViewGroup viewGroup = dynamicViewGroupMapper.selectById(viewConfig.getGroupId());

        LambdaQueryWrapper<DynamicViewColumn> queryWrapper = Wrappers.lambdaQuery();
        queryWrapper.eq(DynamicViewColumn::getViewId, viewConfig.getId());
        List<DynamicViewColumn> viewColumns = dynamicViewColumnMapper.selectList(queryWrapper);

        DimensionQuery query = new DimensionQuery();
        query.setDrillTable(viewConfig.getDrillTable());
        query.setSource(1);
        query.setProvince("江苏省");
        query.setCity("南京市");
        query.setDimension("province");

        List<Join> joinList = new ArrayList<>();

        Table t1 = new Table(viewConfig.getDrillTable());
        t1.setAlias(new Alias("a"));

        // 需要维护人信息
        Table maintainTable = new Table("maintain_map_info");
        maintainTable.setAlias(new Alias("m"));
        if (query.getHasMaintain()) {
            joinList.add(JSqlParserUtil.getMaintainJoin(t1, maintainTable));
        }

        if (Objects.equals(query.getRole(), "ROOT")) {

        } else {
            // 维护人维度
            if (Objects.equals(query.getDimension(), "maintainer")) {
                Table maintainLevelTable = new Table("maintain_level_info");
                maintainLevelTable.setAlias(new Alias("l"));
                joinList.add(JSqlParserUtil.getMaintainLevelJoin(maintainTable, maintainLevelTable));
            }
        }

        List<SelectItem> selectItemList = JSqlParserUtil.getSelectItems(t1, viewColumns);
        additionalSelectItems(selectItemList, query, t1);

        PlainSelect plainSelect = new PlainSelect();
        plainSelect.setFromItem(t1);
        plainSelect.setSelectItems(selectItemList);
        plainSelect.setJoins(joinList);

        Expression where = assembleWhereExpression(t1, query);
        plainSelect.setWhere(where);
        plainSelect.setOrderByElements(JSqlParserUtil.getOrderByElements(req.getSortList()));

        System.out.println(plainSelect);
        return plainSelect.toString();
    }

    public void additionalSelectItems(List<SelectItem> selectItemList, DimensionQuery query, Table table) {
        switch (query.getDimension()) {
            case "city":
            case "province":
                selectItemList.add(new SelectExpressionItem(new Column(table, query.getDimension())));
                break;
            case "customer":
                selectItemList.add(new SelectExpressionItem(new Column(table, "merchant_name")));
                break;
        }
    }

    private Expression assembleWhereExpression(Table t1, DimensionQuery query) {
        Expression expression = null;
        if (query.getSource() != null) {
            EqualsTo equalsTo = new EqualsTo(); // 等于表达式
            equalsTo.setLeftExpression(new Column(t1, "source"));
            equalsTo.setRightExpression(new LongValue(query.getSource()));
            expression = equalsTo;
        }
        if (StringUtils.isNotBlank(query.getProvince())) {
            EqualsTo equalsTo = new EqualsTo(); // 等于表达式
            equalsTo.setLeftExpression(new Column(t1, "province"));
            equalsTo.setRightExpression(new StringValue(query.getProvince()));
            expression = expression == null ? equalsTo : new AndExpression(expression, equalsTo);
        }
        if (StringUtils.isNotBlank(query.getCity())) {
            EqualsTo equalsTo = new EqualsTo(); // 等于表达式
            equalsTo.setLeftExpression(new Column(t1, "city"));
            equalsTo.setRightExpression(new StringValue(query.getCity()));
            expression = expression == null ? equalsTo : new AndExpression(expression, equalsTo);
        }

        return expression;
    }
}
